#include "AbstractClass.h"
#include <iostream>

AbstractClass *AbstractClass::currentApp=NULL;

AbstractClass::AbstractClass(const char *title, int w, int h, int flags ){
	int argc=1;
	char *argv[]={"AbstractClass"};

	glutInit(&argc, argv);

	SetVideoMode(w, h, flags);
	SetTitle(title);

	dispFPS=false;
	curFPS=0.0f;
	lastFPSTime=0;
	fpsCounter=0;

	fpsCountInterval=200;

	getTimerReset=false;
	dispPrint=true;
}

AbstractClass::AbstractClass(int *argcp, char **argv, const char *title, int w, int h, int flags ){
	glutInit(argcp, argv);

	SetVideoMode(w, h, flags);
	SetTitle(title);

	dispFPS=false;
	curFPS=0.0f;
	lastFPSTime=0;
	fpsCounter=0;

	fpsCountInterval=5;

	getTimerReset=false;
	dispPrint=true;
}

AbstractClass::~AbstractClass(){}


void AbstractClass::IdleFunc(){
	currentApp->Idle();
}
void AbstractClass::DisplayFunc(){
	currentApp->Display();
	
	currentApp->PostDisplay();
}
void AbstractClass::UpdateFunc(int value)
{
	currentApp->Update(value);

	currentApp->Redisplay();

	glutTimerFunc(25, UpdateFunc, 0);
}
void AbstractClass::Redisplay(){
	glutPostRedisplay();
}
void AbstractClass::PostDisplay(){
	currentApp->SwapBuffers();
}
void AbstractClass::ReshapeFunc(int w, int h){
	currentApp->windowSize.x=w;
	currentApp->windowSize.y=h;
	currentApp->Reshape(w, h);
}

void AbstractClass::KeyboardFunc(unsigned char key, int x, int y){
	currentApp->Keyboard(key);
}

void AbstractClass::SpecialKeyFunc(int key, int x, int y)
{
    currentApp->SpecialKey(key);
}

void AbstractClass::MouseFunc(int button, int state, int x, int y){
	currentApp->Mouse(button, state, x, y);
}
void AbstractClass::MouseMotionFunc(int x, int y){
	currentApp->MouseMove(x, y);
}

void AbstractClass::MousePassiveMotionFunc(int x, int y){
	currentApp->MousePassiveMove(x, y);
}
///Protected
void AbstractClass::SwapBuffers(){
	glutSwapBuffers();
}

int AbstractClass::SetVideoMode(int w,int h,int flags )
{
	windowSize.x=w;
	windowSize.y=h;
	windowFlags=flags;

	return 0;
}
void AbstractClass::SetTitle(const char *title)
{
	windowTitle=title;
}

void AbstractClass::Run()
{
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB | GLUT_ALPHA | GLUT_STENCIL);
	
	glutInitWindowSize(windowSize.x, windowSize.y);
	windowID=glutCreateWindow(windowTitle.c_str());

	currentApp=this;

	///Callbacks
	glutDisplayFunc(DisplayFunc);
	glutReshapeFunc(ReshapeFunc);
	glutKeyboardFunc(KeyboardFunc);
	glutTimerFunc(25, UpdateFunc, 0);
	glutSpecialFunc(SpecialKeyFunc);
	glutMouseFunc(MouseFunc);
	glutMotionFunc(MouseMotionFunc);
	glutPassiveMotionFunc(MousePassiveMotionFunc);
	glutIdleFunc(IdleFunc);

	this->Init();


	this->lastFrameTime=this->lastFPSTime=glutGet(GLUT_ELAPSED_TIME);

	glutMainLoop();
}
